package start.demo01.datatype.json.entity;

import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import start.demo01.datatype.json.entity.editor.EditorChain;
import start.demo01.datatype.json.interfaces.Factory;
import start.demo01.datatype.json.interfaces.StringEditor;
import start.demo01.datatype.json.json.JSONPath;
import start.demo01.datatype.json.pool.CacheMap;

import java.io.IOException;
import java.sql.SQLException;

import static start.demo01.datatype.json.constant.Constant.*;

@Data
public class DataFactory<T> implements Factory<T, Object> {

    private String result;
    private EditorChain chain;
    private ConfigInfo configInfo;
    private OutputConfig outputConfig;//输出类型

    public DataFactory(String cmdBuild) {
        this.outputConfig = new OutputConfig();
        configInfo = new ConfigInfo();
        chain = EditorChain.builder();
        String[] cmds = cmdBuild.split("\n");
        for (String cmd : cmds) {
            cmd = cmd.trim();
            if (StringUtils.isEmpty(cmd) || cmd.startsWith(IGNORE))
                continue;
            else if (cmd.startsWith("return")) {
                result = cmd.substring(cmd.indexOf("$") + 1);
            } else if (cmd.startsWith("J")) {
                chain.chain(JSONPath.builder(outputConfig, cmd.substring(2)));
            } else if (cmd.startsWith("S")) {
                chain.chain(StringEditor.builder(cmd.substring(2)));
            } else if (cmd.startsWith("conf:")) {
                String info = cmd.substring(5);
                configInfo.build(info);
            }
        }
    }

    @Override
    public Object resolve(CacheMap map, T obj) {
        map.put("$", obj);
        chain.execute(map);//编辑器
        new Thread(() -> {//异步数据输出
            try {
                outputConfig.exec(configInfo, map);
            } catch (SQLException e) {
                System.out.println("sql异常:" + map.get("sql"));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }).start();
        return map.get(result);
    }
}
